<script setup>
import { ref, computed, onMounted } from "vue";
import { MsgType } from "@/stores/chat";
import MarkdownIt from "markdown-it";
import DOMPurify from "dompurify";
import katex from 'katex';
import 'katex/dist/katex.min.css';
import markdownItKatex from 'markdown-it-katex';

const props = defineProps({
    msg: {
        type: Object,
        required: true,
        // 修正props定义方式
        default: () => ({
            id: '',
            content: '',
            role: ''
        }),
        validator: (value) => {
            return 'id' in value && 'content' in value && 'role' in value &&
                   Object.values(MsgType).includes(value.role);
        }
    }
})

const isUser = ref(props.msg.role === MsgType.USER)

// 初始化Markdown解析器，优化数学公式处理
const md = new MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  breaks: true
}).use(markdownItKatex, {
  throwOnError: false,
  errorColor: '#ff0000',
  strict: 'ignore',
  trust: true,
  // 移除全局displayMode设置，让插件自动区分行内和块级公式
  macros: {
    "\\R": "\\mathbb{R}",
    "\\E": "\\mathbb{E}",
    "\\var": "\\text{var}",
    "\\cov": "\\text{cov}"
  }
});

// 配置DOMPurify，允许数学相关标签和属性
const sanitizeOptions = {
  ADD_TAGS: ['math', 'maction', 'maligngroup', 'malignmark', 'menclose', 
             'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 
             'mlongdiv', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 
             'mphantom', 'mroot', 'mrow', 'ms', 'mscarries', 'mscarry', 
             'msgroup', 'msline', 'mspace', 'msqrt', 'msrow', 'mstack', 
             'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 
             'mtr', 'munder', 'munderover', 'semantics', 'annotation', 
             'annotation-xml', 'span'],
  ADD_ATTR: ['mathvariant', 'columnalign', 'rowalign', 'groupalign', 'align', 
             'displaystyle', 'mathsize', 'mathcolor', 'background', 'class'],
  ALLOW_UNKNOWN_PROTOCOLS: true
};

// 安全渲染Markdown，优化公式处理
const renderMarkdown = (content) => {
  if (!content) return '';
  
  // 改进公式预处理，避免影响代码块中的$符号
  let processedContent = content
    // 仅在非代码块中处理公式间距
    .replace(/(^|[^`])(\$[^$]+\$)([^`]|$)/g, (match, p1, p2, p3) => {
      // 检查是否在代码块中
      if (match.includes('```')) {
        return match;
      }
      return `${p1} ${p2} ${p3}`;
    })
    // 优化块级公式格式
    .replace(/(\n|^)\$\$\s*(.*?)\s*\$\$(\n|$)/gs, '\n$$\n$2\n$$\n');
  
  const unsafeHtml = md.render(processedContent);
  return DOMPurify.sanitize(unsafeHtml, sanitizeOptions);
}

// 计算属性处理Markdown内容
const formattedContent = computed(() => {
  return renderMarkdown(props.msg.content);
});

// 监听内容变化，自动调整公式显示
onMounted(() => {
  // 移除直接DOM操作，改用CSS处理样式
});
</script>

<template>
    <div class="item-row" :class="{ 'user-row': isUser }">
        <div class="item-style" :class="{ 'user-style': isUser }">
            <el-avatar 
                class="avatar-style"
                :icon="isUser ? 'Avatar' : 'Platform'"
                :style="{'background-color': isUser ? '#f56a00' : 'rgb(100,149,237)'}"
                />
            <el-card :body-style="{padding: '20px', 'line-height': '1.8'}" 
                shadow="never" class="content-card">
                <div v-html="formattedContent" class="markdown-content"></div>
            </el-card>
        </div>
    </div>
</template>

<style scoped>
.item-row {
    display: flex;
    width: 100%;
    padding: 16px 0;
    justify-content: start;
}

.user-row {
    justify-content: end;
}

.item-style {
    display: flex;
    max-width: 80%;
    padding: 0 15px;
    gap: 16px;
}

.user-style {
    flex-direction: row-reverse;
}

.avatar-style {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    flex-shrink: 0;
}

.content-card {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    border-radius: 8px;
}

.markdown-content {
    width: 100%;
    font-size: 16px;
    line-height: 1.8;
    color: #333;
}

/* 代码块样式 */
:deep(.el-card__body) pre {
    background-color: #f8f9fa;
    padding: 16px;
    border-radius: 6px;
    overflow: auto;
    margin: 1em 0;
    font-size: 14px;
}

:deep(.el-card__body) code {
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
    background-color: rgba(175, 184, 193, 0.2);
    padding: 0.2em 0.4em;
    border-radius: 3px;
    font-size: 90%;
}

/* 引用样式 */
:deep(.el-card__body) blockquote {
    border-left: 4px solid #007bff;
    color: #495057;
    padding: 10px 15px;
    margin: 1em 0;
    background-color: rgba(0, 123, 255, 0.05);
    border-radius: 0 4px 4px 0;
}

/* 段落样式 */
:deep(.el-card__body) p {
    margin: 0em 0;
    text-align: justify;
}

/* 数学公式核心样式优化 */
:deep(.katex) {
    font-size: 1.08em !important; /* 行内公式略大于文本 */
    text-rendering: optimizeLegibility !important;
}

/* 行内公式关键样式 - 使用CSS代替JS操作 */
:deep(.katex:not(.katex-display)) {
    padding: 0.1em 0.3em !important;
    margin: 0 0.15em !important;
    vertical-align: middle !important;
    line-height: 1.2 !important;
}

/* 块级公式样式 */
:deep(.katex-display) {
    display: flex !important;
    justify-content: center !important;
    margin: 1.5em 0 !important;
    overflow: auto hidden !important;
}

/* 优化公式中的符号显示 */
:deep(.katex .mord) {
    margin: 0 0.05em !important;
}

:deep(.katex .mo) {
    margin: 0 0.15em !important; /* 运算符前后间距 */
}

/* 优化上标下标显示 */
:deep(.katex .msup, .katex .msub, .katex .msubsup) {
    margin: 0 0.05em !important;
}

/* 响应式调整 */
@media (max-width: 768px) {
    .item-style {
        max-width: 95%;
    }
    
    :deep(.katex) {
        font-size: 1.05em !important;
    }
}
</style>
